/*
 * Copyright 2024 LY Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.linecorp.android.featureflag.ij.plugin.psi.impl

import com.intellij.navigation.ItemPresentation
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFileFactory
import com.linecorp.android.featureflag.ij.plugin.psi.FeatureFlagFile
import com.linecorp.android.featureflag.ij.plugin.FeatureFlagFileType
import com.linecorp.android.featureflag.ij.plugin.psi.FeatureFlagModifier
import com.linecorp.android.featureflag.ij.plugin.psi.FeatureFlagModifierType
import com.linecorp.android.featureflag.ij.plugin.psi.FeatureFlagProperty
import com.linecorp.android.featureflag.ij.plugin.psi.FeatureFlagTypes
import javax.swing.Icon

/**
 * A class for storing functions used in PSI Element classes generated by Grammar-Kit.
 */
object FeatureFlagPsiImplUtil {

    @JvmStatic
    fun getKey(element: FeatureFlagProperty): String? =
        element.node.findChildByType(FeatureFlagTypes.KEY)?.text

    @JvmStatic
    fun getName(element: FeatureFlagProperty): String? = getKey(element)

    @JvmStatic
    fun setName(element: FeatureFlagProperty, newName: String): PsiElement {
        val keyNode = element.node.findChildByType(FeatureFlagTypes.KEY) ?: return element
        val newKeyNode = PsiFileFactory.getInstance(element.project)
            .createFeatureFlagFile(newName)
            .firstChild
            .firstChild
            .node
        element.node.replaceChild(keyNode, newKeyNode)
        return element
    }

    @JvmStatic
    fun getNameIdentifier(element: FeatureFlagProperty): PsiElement? =
        element.node.findChildByType(FeatureFlagTypes.KEY)?.psi

    @JvmStatic
    fun getPresentation(element: FeatureFlagProperty): ItemPresentation =
        object : ItemPresentation {
            override fun getPresentableText(): String? = element.getKey()

            override fun getLocationString(): String? = element.containingFile?.name

            override fun getIcon(unused: Boolean): Icon? = element.getIcon(0)
        }

    @JvmStatic
    fun getModifierType(element: FeatureFlagModifier): FeatureFlagModifierType? = when {
        element.node.findChildByType(FeatureFlagTypes.MODIFIER_OVERRIDABLE) != null ->
            FeatureFlagModifierType.OVERRIDABLE

        element.node.findChildByType(FeatureFlagTypes.MODIFIER_PRIVATE) != null ->
            FeatureFlagModifierType.PRIVATE

        element.node.findChildByType(FeatureFlagTypes.MODIFIER_LITERALIZE) != null ->
            FeatureFlagModifierType.LITERALIZE

        else -> null
    }

    private fun PsiFileFactory.createFeatureFlagFile(name: String): FeatureFlagFile =
        createFileFromText("FEATURE_FLAG", FeatureFlagFileType, "$name = OFF") as FeatureFlagFile
}
